package com.alibaba.citrus.cr.b2b.trade.order.facade.service;

import com.alibaba.acm.shaded.com.google.common.collect.Lists;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.annotation.ProcessInvoker;
import com.alibaba.citrus.cr.common.constant.SaleOrderConstants;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderTypeEnum;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.lock.SaleRedisLock;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.alibaba.nacos.common.utils.MapUtils;
import com.epoch.app.bcorder.platform_enhance.SaleOrderTag;
import com.epoch.app.crb2btradecenter.api.orderlinewrite.service.OrderLineWriteService;
import com.epoch.app.crb2btradecenter.api.orderquery.service.OrderQueryService;
import com.epoch.app.crb2btradecenter.api.trademessagelistener.dto.ConsignmentDeleteMessageDealRequest;
import com.epoch.app.crb2btradecenter.api.trademessagelistener.dto.ConsignmentOrderCreateMessageDealRequest;
import com.epoch.app.crb2btradecenter.api.trademessagelistener.dto.ConsignmentUpdateOrderDeliveryQtyMessageDealRequest;
import com.epoch.app.crb2btradecenter.api.trademessagelistener.dto.InvoiceCreateMessageDealRequest;
import com.epoch.app.crb2btradecenter.api.trademessagelistener.service.TradeMessageListenerService;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.LoadOrderLineRequest;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.OrderLineLoadListRequest;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.UpdateCumulativeDeliveryQuantityRequest;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.UpdateCumulativeDeliveryQuantityResponse;
import com.epoch.app.crb2btradecenter.domain.orderline.model.OrderLine;
import com.epoch.app.crb2btradecenter.domain.orderline.service.OrderLineService;
import com.epoch.app.crb2btradecenter.dto.request.OrderPageQueryRequest;
import com.epoch.app.crb2btradecenter.dto.response.OrderPageQueryResponse;
import com.epoch.app.crb2btradecenter.model.dto.FeaturesUpdateRequest;
import com.epoch.app.crb2btradecenter.model.dto.SubFeaturesRequest;
import com.epoch.app.crforecastsales.activityuserecordrelation.dto.QueryActivityUseRecordRelationByIdAndItemResponse;
import com.epoch.app.crforecastsales.activityuserecordrelation.dto.UpdateActivityRecordRequest;
import com.epoch.app.crforecastsales.activityuserecordrelation.service.ActivityUseRecordRelationService;
import com.epoch.app.crforecastsales.domian.activityterm.dto.QueryTermSDOListByTermIdRequest;
import com.epoch.app.crforecastsales.domian.activityterm.dto.UpdateActivityTermResponse;
import com.epoch.app.crforecastsales.domian.activityterm.service.ActivityTermService;
import com.epoch.app.crforecastsales.domian.activitytitle.dto.QueryActivityTitleByActivityIdRequest;
import com.epoch.app.crforecastsales.domian.activitytitle.service.ActivityTitleService;
import com.epoch.app.crforecastsales.domian.activitytitleext.dto.UpdateActivityTitleExtForVersionResponse;
import com.epoch.app.crforecastsales.domian.activitytitleext.model.ActivityTitleExt;
import com.epoch.app.crforecastsales.domian.activitytitleext.service.ActivityTitleExtService;
import com.epoch.app.crforecastsales.model.dto.*;
import com.epoch.app.crpricecenter.model.enums.ActivityTypeEnum;
import com.epoch.app.crpricecenter.sdo.ActivityUseRecordRelationSDO;
import com.epoch.app.crunifiedinventory.consignmentorder.model.ConsignmentOrder;
import com.epoch.app.crunifiedinventory.consignmentorder.service.ConsignmentOrderService;
import com.epoch.app.crunifiedinventory.consignmentorderline.dto.BatchQueryRequest;
import com.epoch.app.crunifiedinventory.consignmentorderline.model.ConsignmentOrderLine;
import com.epoch.app.crunifiedinventory.consignmentorderline.service.ConsignmentOrderLineService;
import com.epoch.app.crunifiedinventory.domain.allocateorder.dto.AllocateOrderLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorder.model.AllocateOrder;
import com.epoch.app.crunifiedinventory.domain.allocateorder.service.AllocateOrderService;
import com.epoch.app.crunifiedinventory.model.dto.ConsignmentOrderLoadListRequest;
import com.epoch.app.crunifiedinventory.sdo.ConsignmentOrderLineSDO;
import com.epoch.app.crunifiedinventory.sdo.ConsignmentOrderSDO;
import com.epoch.app.crunifiedinventory.sdo.InvoiceOrderDetailSDO;
import com.epoch.app.crunifiedinventory.sdo.InvoiceOrderSDO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: qianlei
 * @create: 2021/11/10 11:54
 */
@Component
@Primary
public class TradeMessageListenerServiceImpl implements TradeMessageListenerService {

    @Autowired
    private OrderLineWriteService orderLineWriteService;
//    @Autowired
//    private OrderLineQueryServiceRepository orderLineQueryServiceRepository;
    @Autowired
    private OrderQueryService orderQueryService;
    @Autowired
    private ActivityUseRecordRelationService activityUseRecordRelationService;
//    @Autowired
//    private ForecastOrderQueryService forecastOrderQueryService;
//    @Autowired
//    private ForecastOrderLineQueryService forecastOrderLineQueryService;
    @Autowired
    private ActivityTermService activityTermService;
    @Autowired
    private ActivityTitleService activityTitleService;
    @Autowired
    private ActivityTitleExtService activityTitleExtService;

    @Autowired
    private OrderLineService orderLineService;

    @Resource
    private AllocateOrderService allocateOrderService;
    @Resource
    private ConsignmentOrderService consignmentOrderService;
    @Resource
    private ConsignmentOrderLineService consignmentOrderLineService;

    private final static ArrayList<String> replenishList = Lists.newArrayList(ActivityTypeEnum.REPLENISH_LIST.getValue().split(","));

    private final Log log = Log.getLogger(TradeMessageListenerServiceImpl.class);

    private final String EXCHANGE = "exchange";

    @Override
    @FacadeInvoker
    public Result<Void> consignmentOrderCreateMessageDeal(ConsignmentOrderCreateMessageDealRequest consignmentOrderCreateMessageDealRequest) {
        log.info("TradeMessageListenerServiceImpl messageJSON:" + consignmentOrderCreateMessageDealRequest.getOrderJson());
        //解析消息
        ConsignmentOrderSDO consignmentOrderSDO = JSONObject.parseObject(consignmentOrderCreateMessageDealRequest.getOrderJson(),ConsignmentOrderSDO.class);
//        try {
//           // Thread.sleep(8000);
//        } catch (InterruptedException e) {
////            e.printStackTrace();
//            //todo sap需保证 回调在交货单同步之前，否则需一直保留该处理方式
//            log.info("交货单同步时，睡眠等待5s，线程异常");
//        }
        //如果不是销售订单交货单，直接返回不处理
        if (StringUtil.isBlank(consignmentOrderSDO.getOuterSalesOrderId())) {
            return Result.success(null);
        }
        // 睡眠方式暂不能控制和015之间的并发，因此目前仍需以外部单号加锁控制
        String lockKey = "sapSync:" + consignmentOrderSDO.getOuterSalesOrderId();
        try(SaleRedisLock lock = new SaleRedisLock("REDIS_CACHE",lockKey, 0, 10 * 60 * 1000)) {
            //加锁
            log.info("consignmentOrderCreateMessageDeal 加锁" + lockKey + "时间:"+ new Date());
            if (!lock.lock()) {
                log.error("consignmentOrderCreateMessageDeal017获取锁失败|外部单号为:" + lockKey);
                throw new FunctionException("OTS-04-001-00-15-038");
            }
            log.info("ThreadId:"+Thread.currentThread().getId()+"|SaleRedis.key="+lockKey+"|lock");
            OrderPageQueryRequest orderPageQueryRequest = new OrderPageQueryRequest();
            orderPageQueryRequest.setOuterOrderId(consignmentOrderSDO.getOuterSalesOrderId());
            Result<List<OrderPageQueryResponse>> result = orderQueryService.pageQuery(orderPageQueryRequest);
            log.info("查询销售订单结果：" + JSON.toJSONString(result));
            if (result == null || CollectionUtils.isEmpty(result.getResult())) {
                log.info("交货单同步时，更新销售订单信息，未查询到销售订单，SAP单号：" + consignmentOrderSDO.getOuterSalesOrderId());
                throw new FacadeException("OTS-05-001-10-16-036");
            }
            OrderPageQueryResponse resp = result.getResult().get(0);

            OrderLineLoadListRequest orderLineLoadListRequest = new OrderLineLoadListRequest();
            orderLineLoadListRequest.setMainOrderId(resp.getId());
            orderLineLoadListRequest.setStart(0);
            orderLineLoadListRequest.setLimit(999);
            Result<List<OrderLine>> listResult = orderLineService.loadOrderLineList(orderLineLoadListRequest);

            if (Objects.isNull(listResult) || CollectionUtils.isEmpty(listResult.getResult())) {
                log.info("consignmentOrderCreateMessageDeal :未查到子单信息");
                return Result.success(null);
            }

            Map<String, ConsignmentOrderLineSDO> consignmentOrderLineSDOMap = new HashMap<>();

            if (CollectionUtils.isNotEmpty(consignmentOrderSDO.getConsignmentOrderLineSDOS())) {
                for (ConsignmentOrderLineSDO consignmentOrderLineSDO : consignmentOrderSDO.getConsignmentOrderLineSDOS()) {
                    if (consignmentOrderSDO.getOuterSalesOrderId() == null || consignmentOrderLineSDO.getOuterSoLineId() == null) {
                        return Result.success(null);
                    }
                    consignmentOrderLineSDOMap.put(consignmentOrderLineSDO.getOuterSoLineId(), consignmentOrderLineSDO);
                }
            }

            //add by 皓晖 at 20211216 for 同步更新信息丢失问题 begin
            //更新销售订单信息
            Map<String, String> mainOrderFeaturesToUpdate = new HashMap<>();
            mainOrderFeaturesToUpdate.put(SaleOrderConstants.DELIVERY_ORDER_ID, consignmentOrderSDO.getOuterDeliveryOrderId());
            //如果是换货订单 就多存一次交货单号
            boolean isExchangeOrder = isExchangeOrder(resp.getOrderType());
            if (isExchangeOrder){
                mainOrderFeaturesToUpdate.put(SaleOrderConstants.EXCHANGE_ORDER_DELIVERY_ORDER_ID,consignmentOrderSDO.getOuterDeliveryOrderId());
            }
            FeaturesUpdateRequest featuresUpdateRequest = new FeaturesUpdateRequest();
            featuresUpdateRequest.setMainOrderId(resp.getId());
            featuresUpdateRequest.setOrderSyncVersionToCheck(resp.getSyncVersion());
            featuresUpdateRequest.setMainOrderFeaturesToUpdate(mainOrderFeaturesToUpdate);

            //add by myw at 20220806 for 交货单创建应该清楚销售单消息说明
            Map<String, String> mainOrderFeaturesToDelete = new HashMap<>();
            mainOrderFeaturesToDelete.put(SaleOrderConstants.EXT_MESSAGE,"" );
            featuresUpdateRequest.setMainOrderFeaturesToDelete(mainOrderFeaturesToDelete);

            this.orderLineWriteService.updateFeatures(featuresUpdateRequest);


            for (OrderLine orderLine : listResult.getResult()) {
                if (StringUtils.isBlank(orderLine.getOuterOrderLineId())){
                    log.info("consignmentOrderCreateMessageDeal :015未更新外部子单行号");
                    throw new FunctionException("OTS-05-001-10-16-051");
                }
                //如果是换货的 需要判断当前line 是否属于该交货单类型 根据交货单明细的ots行号来判断
                boolean isExchangeLine = false;
                boolean isExchangeDeliveryOrder = false;
                if (isExchangeOrder && CollectionUtils.isNotEmpty(consignmentOrderSDO.getConsignmentOrderLineSDOS())){
                    isExchangeDeliveryOrder= consignmentOrderSDO.getConsignmentOrderLineSDOS().stream().anyMatch(x -> StringUtils.isNotBlank(x.getSoLineId())
                            && Integer.parseInt(x.getSoLineId()) % 2 == 0);
                    isExchangeLine = EXCHANGE.equals(orderLine.getOrderLineTag());
                    log.info("TradeMessageListenerServiceImpl_consignmentOrderCreateMessageDeal_exchangeBool:order:{},line:{}",isExchangeDeliveryOrder,isExchangeLine);
                }
                //交货单的sap行号 - ots的sap行号 如果有这行
                if (consignmentOrderLineSDOMap.containsKey(orderLine.getOuterOrderLineId())) {
                    Map<String, SubFeaturesRequest> subOrderFeaturesToUpdate = new HashMap<>();
                    //需更新添加的交货单信息
                    Map<String, String> features = new HashMap<>();
                    ConsignmentOrderLineSDO consignmentOrderLineSDO = consignmentOrderLineSDOMap.get(orderLine.getOuterOrderLineId());
                    features.put(SaleOrderConstants.DELIVERY_ORDER_ID, consignmentOrderSDO.getOuterDeliveryOrderId());
                    //如果是换货行的
                    if (isExchangeOrder(resp.getOrderType())){
                        features.put(SaleOrderConstants.EXCHANGE_ORDER_DELIVERY_ORDER_ID,consignmentOrderSDO.getOuterDeliveryOrderId());
                    }
//                    features.put
                    features.put(SaleOrderConstants.DELIVERY_ORDER_ID_STRING_BUILDER, consignmentOrderSDO.getOuterDeliveryOrderId()+"/");
                    features.put(SaleOrderConstants.DELIVERY_ORDER_LINE_NO, consignmentOrderLineSDO.getOuterOrderLineId());
                    features.put(SaleOrderConstants.DELIVERY_ORDER_CREATOR, consignmentOrderSDO.getCreator());
                    features.put(SaleOrderConstants.DELIVERY_ORDER_CREAT_DATE, DateUtils.toDateStr(consignmentOrderSDO.getCreatDate().getTime(), DateUtils.DATETIME_FORMAT));
                    features.put(SaleOrderConstants.DELIVERY_ORDER_QTY, consignmentOrderLineSDO.getQty());
                    features.put(SaleOrderConstants.DELIVERY_ORDER_POD_STATUS, consignmentOrderLineSDO.getPodStatus());
                    features.put(SaleOrderConstants.DELIVERY_ORDER_POD_QTY, consignmentOrderLineSDO.getPodQty());
//                features.put(SaleOrderConstants.DELIVERY_ORDER_DATE, DateUtils.toDateStr(consignmentOrderSDO.getDeliveryDate().getTime(), DateUtils.DATETIME_FORMAT));
                    features.put(SaleOrderConstants.DELIVERY_BASE_QUANTITY, consignmentOrderLineSDO.getBasicQuantity());
//        features.put(SaleOrderConstants.DELIVERY_ORDER_ZK99,consignmentOrderSDO.getOuterDeliveryOrderId());
//        features.put(SaleOrderConstants.DELIVERY_ORDER_KZWI1,consignmentOrderSDO.getOuterDeliveryOrderId());
                    // fixme 交货单数量单独处理
                    if (StringUtils.isNotBlank(orderLine.getFeatures())) {
                        Map<String, String> orderLineFeatures = JSONObject.parseObject(orderLine.getFeatures(),Map.class);
                        String deliveryQty = orderLineFeatures.get(SaleOrderConstants.DELIVERY_ORDER_QTY);
                        String basicQty = orderLineFeatures.get(SaleOrderConstants.DELIVERY_BASE_QUANTITY);
                        String deliveryId = orderLineFeatures.get(SaleOrderConstants.DELIVERY_ORDER_ID);
                        String doibuilders = orderLineFeatures.get(SaleOrderConstants.DELIVERY_ORDER_ID_STRING_BUILDER);
                        //交货单数量非空，并且交货单不重复，则进行交货单数量累加
                        if (StringUtils.isNotBlank(deliveryQty) && (StringUtils.isBlank(deliveryId) || !deliveryId.equals(consignmentOrderSDO.getOuterDeliveryOrderId()))){
                            log.info("consignmentOrderCreateMessageDeal 销售订单一行多个交货单:" + consignmentOrderSDO.getOuterDeliveryOrderId());
                            BigDecimal qty = new BigDecimal(deliveryQty.trim());
                            if (StringUtils.isNotBlank(consignmentOrderLineSDO.getQty())){
                                qty = qty.add(new BigDecimal(consignmentOrderLineSDO.getQty().trim()));
                            }

                            BigDecimal bQty = new BigDecimal(basicQty.trim());
                            if (StringUtils.isNotBlank(consignmentOrderLineSDO.getBasicQuantity())){
                                bQty = bQty.add(new BigDecimal(consignmentOrderLineSDO.getBasicQuantity().trim()));
                            }
                            features.put(SaleOrderConstants.DELIVERY_BASE_QUANTITY, bQty.setScale(3, RoundingMode.DOWN).toString());
                            features.put(SaleOrderConstants.DELIVERY_ORDER_QTY, qty.setScale(3, RoundingMode.DOWN).toString());
                            features.put(SaleOrderConstants.DELIVERY_ORDER_ID_STRING_BUILDER, doibuilders + consignmentOrderSDO.getOuterDeliveryOrderId() + "/");
                        }
                        if (StringUtils.isNotBlank(basicQty) && (StringUtils.isBlank(deliveryId) || !deliveryId.equals(consignmentOrderSDO.getOuterDeliveryOrderId()))){
                            BigDecimal bQty = new BigDecimal(basicQty.trim());
                            if (StringUtils.isNotBlank(consignmentOrderLineSDO.getBasicQuantity())){
                                bQty = bQty.add(new BigDecimal(consignmentOrderLineSDO.getBasicQuantity().trim()));
                            }
                            features.put(SaleOrderConstants.DELIVERY_BASE_QUANTITY, bQty.setScale(3, RoundingMode.DOWN).toString());
                        }
                    }

                    SubFeaturesRequest subFeaturesRequest = new SubFeaturesRequest();
                    subFeaturesRequest.setSubOrderFeaturesToUpdate(features);
                    //add by 皓晖 at 20211216 for 同步更新增加版本号 begin
                    subFeaturesRequest.setSyncVersion(orderLine.getSyncVersion());
                    //add by 皓晖 at 20211216 for 同步更新增加版本号 end
                    subOrderFeaturesToUpdate.put(String.valueOf(orderLine.getId()), subFeaturesRequest);

                    FeaturesUpdateRequest subFeaturesUpdateRequest = new FeaturesUpdateRequest();
                    subFeaturesUpdateRequest.setMainOrderId(orderLine.getMainOrderId());
                    subFeaturesUpdateRequest.setSubOrderFeaturesToUpdate(subOrderFeaturesToUpdate);

                    orderLineWriteService.updateFeatures(subFeaturesUpdateRequest);

                    //促销活动根据交货单进行相关的回补
                    //根据销售单的前序预报单号 加货品外部编码查询出对应的 活动占用记录
                    //再根据活动占用记录上的活动元数据进行相应的term占用数量和占用金额回补
                    String frontOrderId = resp.getFrontOrderId();
                    if (StringUtils.isNotBlank(frontOrderId)){
                        deliveryRollBackActivity(orderLine, consignmentOrderLineSDO, frontOrderId,Boolean.FALSE);
                    }


                } else {

                    //判断一下是否是换货订单 如果是换货订单 就不清除了.
                    if (isExchangeOrder && !Objects.equals(isExchangeDeliveryOrder,isExchangeLine)){
                        log.info("TradeMessageListenerServiceImpl_consignmentOrderCreateMessageDeal_exchangeOrder");
                        continue;
                    }

                    Map<String, SubFeaturesRequest> subOrderFeaturesToDelete = new HashMap<>();
                    //交货单信息
                    List<String> features = new ArrayList<>();
                    features.add(SaleOrderConstants.DELIVERY_ORDER_ID);
                    features.add(SaleOrderConstants.DELIVERY_ORDER_LINE_NO);
                    features.add(SaleOrderConstants.DELIVERY_ORDER_CREATOR);
                    features.add(SaleOrderConstants.DELIVERY_ORDER_CREAT_DATE);
                    features.add(SaleOrderConstants.DELIVERY_ORDER_QTY);
                    features.add(SaleOrderConstants.DELIVERY_ORDER_POD_STATUS);
                    features.add(SaleOrderConstants.DELIVERY_ORDER_POD_QTY);
                    features.add(SaleOrderConstants.DELIVERY_ORDER_DATE);
                    features.add(SaleOrderConstants.DELIVERY_BASE_QUANTITY);

                    //发票信息
                    features.add(SaleOrderConstants.INVOICE_ID);
                    features.add(SaleOrderConstants.INVOICE_NO);
                    features.add(SaleOrderConstants.INVOICE_TYPE);
                    features.add(SaleOrderConstants.INVOICE_DATE);
                    features.add(SaleOrderConstants.INVOICE_CREATOR);
                    features.add(SaleOrderConstants.INVOICE_CREATE_TIME);
                    features.add(SaleOrderConstants.INVOICE_QTY);
                    features.add(SaleOrderConstants.INVOICE_PRICE);
                    features.add(SaleOrderConstants.INVOICE_ZK01_FEE);

                    SubFeaturesRequest subFeaturesRequest = new SubFeaturesRequest();
                    subFeaturesRequest.setSubOrderFeaturesToDelete(features);

                    subFeaturesRequest.setSyncVersion(orderLine.getSyncVersion());
                    subOrderFeaturesToDelete.put(String.valueOf(orderLine.getId()), subFeaturesRequest);

                    FeaturesUpdateRequest subFeaturesUpdateRequest = new FeaturesUpdateRequest();
                    subFeaturesUpdateRequest.setMainOrderId(orderLine.getMainOrderId());
                    subFeaturesUpdateRequest.setSubOrderFeaturesToDelete(subOrderFeaturesToDelete);

                    orderLineWriteService.updateFeatures(subFeaturesUpdateRequest);
                }
            }

//            //add by 皓晖 at 20211216 for 同步更新信息丢失问题 end
//
//            List<ConsignmentOrderLineSDO> consignmentOrderLineSDOS = consignmentOrderSDO.getConsignmentOrderLineSDOS();
//            for (ConsignmentOrderLineSDO consignmentOrderLineSDO : consignmentOrderLineSDOS) {
//                if (consignmentOrderSDO.getOuterSalesOrderId() == null || consignmentOrderLineSDO.getOuterSoLineId() == null) {
//                    return Result.success(null);
//                }
//
//                OrderLineLoadListRequest orderLinePageQueryRequest = new OrderLineLoadListRequest();
//                orderLinePageQueryRequest.setMainOrderId(resp.getId());
//                orderLinePageQueryRequest.setOuterOrderLineId(consignmentOrderLineSDO.getOuterSoLineId());
//                Result<List<OrderLine>> orderLineList = orderLineService.loadOrderLineList(orderLinePageQueryRequest);
//                if (CollectionUtils.isEmpty(orderLineList.getResult())) {
//                    log.info("交货单同步时，更新销售订单信息，未查询到销售订单，SAP单号：" + consignmentOrderSDO.getOuterSalesOrderId());
//                    throw new FacadeException("未查询到销售订单行");
//                }
//                OrderLine orderLine = orderLineList.getResult().get(0);
//                //交货单信息
//                Map<String, String> features = new HashMap<>();
//                features.put(SaleOrderConstants.DELIVERY_ORDER_ID, consignmentOrderSDO.getOuterDeliveryOrderId());
//                features.put(SaleOrderConstants.DELIVERY_ORDER_LINE_NO, consignmentOrderLineSDO.getOuterOrderLineId());
//                features.put(SaleOrderConstants.DELIVERY_ORDER_CREATOR, consignmentOrderSDO.getCreator());
//                features.put(SaleOrderConstants.DELIVERY_ORDER_CREAT_DATE, DateUtils.toDateStr(consignmentOrderSDO.getCreatDate().getTime(), DateUtils.DATETIME_FORMAT));
//                features.put(SaleOrderConstants.DELIVERY_ORDER_QTY, consignmentOrderLineSDO.getQty());
//                features.put(SaleOrderConstants.DELIVERY_ORDER_POD_STATUS, consignmentOrderLineSDO.getPodStatus());
//                features.put(SaleOrderConstants.DELIVERY_ORDER_POD_QTY, consignmentOrderLineSDO.getPodQty());
////                features.put(SaleOrderConstants.DELIVERY_ORDER_DATE, DateUtils.toDateStr(consignmentOrderSDO.getDeliveryDate().getTime(), DateUtils.DATETIME_FORMAT));
//                features.put(SaleOrderConstants.DELIVERY_BASE_QUANTITY, consignmentOrderLineSDO.getBasicQuantity());
////        features.put(SaleOrderConstants.DELIVERY_ORDER_ZK99,consignmentOrderSDO.getOuterDeliveryOrderId());
////        features.put(SaleOrderConstants.DELIVERY_ORDER_KZWI1,consignmentOrderSDO.getOuterDeliveryOrderId());
//
//                Map<String, SubFeaturesRequest> subOrderFeaturesToUpdate = new HashMap<>();
//                SubFeaturesRequest subFeaturesRequest = new SubFeaturesRequest();
//                subFeaturesRequest.setSubOrderFeaturesToUpdate(features);
//                //add by 皓晖 at 20211216 for 同步更新增加版本号 begin
//                subFeaturesRequest.setSyncVersion(orderLine.getSyncVersion());
//                //add by 皓晖 at 20211216 for 同步更新增加版本号 end
//                subOrderFeaturesToUpdate.put(String.valueOf(orderLine.getId()), subFeaturesRequest);
//
//                FeaturesUpdateRequest subFeaturesUpdateRequest = new FeaturesUpdateRequest();
//                subFeaturesUpdateRequest.setMainOrderId(orderLine.getMainOrderId());
//                subFeaturesUpdateRequest.setSubOrderFeaturesToUpdate(subOrderFeaturesToUpdate);
//
//                orderLineWriteService.updateFeatures(subFeaturesUpdateRequest);
//
//            }
        } catch (Exception e) {
            log.error("更新订单features交货单信息失败:", e);
            throw new FacadeException("OTS-05-001-10-16-035");
        }

        return Result.success(null);
    }

    private boolean deliveryRollBackActivity(OrderLine orderLine, ConsignmentOrderLineSDO consignmentOrderLineSDO, String frontOrderId, Boolean isDelete) {
        log.info("交货单回补开始!交货单号:" + consignmentOrderLineSDO.getConsignmentOrderId()
                +"销售单号:"+orderLine.getMainOrderBizId()
                +"外部行号:"+consignmentOrderLineSDO.getOuterSoLineId()
                + "物料编码:" + orderLine.getScItemOutCode()
                + "操作类型:" + (isDelete ? "删除" : "回补"));
        ActivityUseRecordRelationLoadListVO activityUseRecordRelationLoadListVO = new ActivityUseRecordRelationLoadListVO();
        activityUseRecordRelationLoadListVO.setMainOrderId(frontOrderId);
        activityUseRecordRelationLoadListVO.setSubOrderId(orderLine.getFrontOrderLineId());

        String features = orderLine.getFeatures();
        if (StringUtils.isBlank(features)){
            return false;
        }
        JSONObject orderLineFeatures = JSONObject.parseObject(features);
        //确认生成销售单序列号，作为活动回补确认时机关键key
        String sequenceNo = orderLineFeatures.getString("sequenceNo");
        activityUseRecordRelationLoadListVO.setSequenceNo(sequenceNo);
        QueryActivityUseRecordRelationByIdAndItemResponse recordRelation = activityUseRecordRelationService.queryActivityUseRecordRelationByIdAndItem(activityUseRecordRelationLoadListVO);
        QueryActivityTitleByActivityIdRequest queryActivityTitleByActivityIdRequest = new QueryActivityTitleByActivityIdRequest();


        if (Objects.nonNull(recordRelation)&&CollectionUtils.isNotEmpty(recordRelation.getResult())){
            for (ActivityUseRecordRelationSDO activityUseRecordRelationSDO : recordRelation.getResult()) {
//            ActivityUseRecordRelationSDO activityUseRecordRelationSDO = recordRelation.getResult().get(0);
            String activityTermId = activityUseRecordRelationSDO.getActivityTermId();
            String activityId = activityUseRecordRelationSDO.getActivityId();

            Integer itemQuantity = activityUseRecordRelationSDO.getItemQuantity();
            Long activityOccupyFee = activityUseRecordRelationSDO.getActivityOccupyFee();
            String podStatus = consignmentOrderLineSDO.getPodStatus();
            //活动删除 将交货单数量置为0 ，来进行活动回补
            String podQty = isDelete ? String.valueOf(orderLine.getQuantity()) : consignmentOrderLineSDO.getPodQty();
            String qty = isDelete ? String.valueOf(orderLine.getQuantity()) : consignmentOrderLineSDO.getQty();
            Integer deliveryOrderLineQty = (StringUtils.isNotBlank(podStatus) && "B".equals(podStatus)) ? new BigDecimal(podQty).intValue() : new BigDecimal(qty).intValue();
            queryActivityTitleByActivityIdRequest.setActivityId(activityId);
            ActivityTitleLoadListVO activityTitleLoadListVO = activityTitleService.queryActivityTitleByActivityId(queryActivityTitleByActivityIdRequest);
            if (Objects.isNull(activityTitleLoadListVO)) {
                log.warn("交货单回补活动失败!活动不存在" + activityId);
                return true;
            }
            //活动类型
            String activityFacadeCode = activityTitleLoadListVO.getActivityFacadeCode();
            //是否按组管控
            String controlByGroupFlag = activityTitleLoadListVO.getControlByGroupFlag();
            //活动便签号
            String activityNoteId = activityTitleLoadListVO.getActivityNoteId();

            //交货单数量小于活动占用数量,应该进行回补
//            if (itemQuantity>deliveryOrderLineQty){
            String activityPrice = orderLine.getActivityPrice();
            String unitPrice = orderLine.getUnitPrice();
            long shouldOccupyFee;
            //活动占用费用差值 交货单占用费用-销售单占用费用
            long diffOccupyFee;
            //活动占用数量差值 交货单占用数量-销售单占用数量
            int diffQuantity = deliveryOrderLineQty - itemQuantity;
            //ZS03为特价活动 有活动价格 单个活动占用单价=（常规单价-活动价格）
            if ("ZS03".equals(activityFacadeCode)) {
                //特价活动，拆单的特价单才需要交货单回补
                if (StringUtils.isBlank(orderLine.getActivityCode())){
                    continue;
                }
                shouldOccupyFee = (new BigDecimal(unitPrice).subtract(new BigDecimal(activityPrice))).multiply(new BigDecimal(deliveryOrderLineQty)).longValue();
            } else {
                //交货单数量*常规单价
                BigDecimal multiply = new BigDecimal(unitPrice).multiply(new BigDecimal(deliveryOrderLineQty));
                if ("ZS01".equals(activityFacadeCode) || "ZS02".equals(activityFacadeCode)) {
                    //一个预报子单生成的搭赠活动，赠品明细的活动编码为空，应该只回补金额
                    // 如果活动编码不为空则是买品明细，应该在交货单回补的时候只回补数量
                    if (StringUtils.isNotBlank(orderLine.getActivityCode())){
                        shouldOccupyFee=activityOccupyFee;
                    }else {
                        diffQuantity=0;
                        shouldOccupyFee = multiply.longValue();
                    }
                } else if (replenishList.contains(activityFacadeCode)){
                    //补货订单类型交货单回补 只回补活动金额 交货单数量*单价=占用金额
                    diffQuantity=0;
                    shouldOccupyFee= multiply.longValue();
                }else {
                    log.warn("交货单回补活动失败!活动类型不支持!活动号:" + activityId + "活动类型:" + activityFacadeCode);
                    return true;
                }
            }
            diffOccupyFee = shouldOccupyFee - activityOccupyFee;

            //回补活动占用
            UpdateActivityRecordRequest updateActivityRecordRequest = new UpdateActivityRecordRequest();
            updateActivityRecordRequest.setRecordId(activityUseRecordRelationSDO.getId());
            updateActivityRecordRequest.setVersion(activityUseRecordRelationSDO.getVersion());

            //赠品行更新占用时，数量要还原
            deliveryOrderLineQty=diffQuantity+itemQuantity;
            updateActivityRecordRequest.setOccupyQuantity((long) deliveryOrderLineQty);
            updateActivityRecordRequest.setOccupyFee(shouldOccupyFee);
            updateActivityRecordRequest.setStatus(1);
//            if (isDelete) {
//                updateActivityRecordRequest.setStatus(-1);
//            }
            log.info("更新活动占用记录表对象:"+JSON.toJSONString(updateActivityRecordRequest));
            Result<Boolean> updateActivityRecord = activityUseRecordRelationService.updateActivityRecord(updateActivityRecordRequest);
            if (Objects.isNull(updateActivityRecord) || !updateActivityRecord.getResult() || !updateActivityRecord.isSuccess()) {
                log.warn("回补活动占用失败!更新活动占用记录失败!" + JSON.toJSONString(updateActivityRecordRequest));
                return true;
            }

            //回补活动term reload term表再重新计算占用值
            //需考虑是否是按组管控的活动，如果是按组管控的活动 ext表也需要做相应的占用量的回补
            QueryTermSDOListByTermIdRequest queryTermSDOListByTermIdRequest = new QueryTermSDOListByTermIdRequest();
            queryTermSDOListByTermIdRequest.setActivityId(activityId);
            queryTermSDOListByTermIdRequest.setTermId(activityTermId);
            ActivityTermLoadListVO activityTermLoadListVO = activityTermService.queryTermSDOListByTermId(queryTermSDOListByTermIdRequest);
            if (Objects.isNull(activityTermLoadListVO)) {
                log.warn("交货单回补活动失败!活动Term不存在,活动号:" + activityId + "Term号:" + activityTermId);
                return true;
            }
            Integer originTermOccupyQuantity = Nullable.of(activityTermLoadListVO.getActivityOccupyQuantity()).orElse(0);
            Long originTermOccupyFee = Nullable.of(activityTermLoadListVO.getActivityOccupyFee()).orElse(0L);

            int nowTermOccupyQuantity = originTermOccupyQuantity + diffQuantity;
            long nowTermOccupyFee = originTermOccupyFee + diffOccupyFee;


            ActivityTermUpdateRequest activityTermUpdateRequest = new ActivityTermUpdateRequest();
            BeanUtils.copyProperties(activityTermLoadListVO,activityTermUpdateRequest);

            activityTermUpdateRequest.setId(activityTermLoadListVO.getId());
            activityTermUpdateRequest.setActivityOccupyQuantity(nowTermOccupyQuantity);
            activityTermUpdateRequest.setActivityOccupyFee(nowTermOccupyFee);
            activityTermUpdateRequest.setVersion(activityTermLoadListVO.getVersion());
            log.info("更新活动Term表对象:"+JSON.toJSONString(activityTermUpdateRequest));
            UpdateActivityTermResponse updateActivityTermResponse = activityTermService.updateActivityTerm(activityTermUpdateRequest);
            if (Objects.isNull(updateActivityTermResponse) || Objects.isNull(updateActivityTermResponse.getCount()) || updateActivityTermResponse.getCount() == 0) {
                log.warn("交货单回补活动失败!更新活动Term失败!" + JSON.toJSONString(activityTermUpdateRequest));
                return true;
            }

            if (StringUtils.isNotBlank(controlByGroupFlag) && "X".equals(controlByGroupFlag)) {
                ActivityTitleExtCreateRequest activityTitleExtCreateRequest = new ActivityTitleExtCreateRequest();
                activityTitleExtCreateRequest.setActivityNoteId(activityNoteId);
                ActivityTitleExt activityTitleExt = activityTitleExtService.queryActivityTitleExt(activityTitleExtCreateRequest);
                if (Objects.isNull(activityTitleExt)) {
                    log.warn("交货单回补活动失败!活动Ext不存在,便签号:" + activityNoteId);
                    return true;
                }

                Long originExtOccupyQuantity = Nullable.of(activityTitleExt.getActivityOccupyQuantity()).orElse(0L);
                Long originExtOccupyFee = Nullable.of(activityTitleExt.getActivityOccupyFee()).orElse(0L);

                long nowExtOccupyQuantity = originExtOccupyQuantity + diffQuantity;
                long nowExtOccupyFee = originExtOccupyFee + diffOccupyFee;
                ActivityTitleExtUpdateRequest activityTitleExtUpdateRequest = new ActivityTitleExtUpdateRequest();
                BeanUtils.copyProperties(activityTitleExt, activityTitleExtUpdateRequest);

                activityTitleExtUpdateRequest.setActivityOccupyQuantity(nowExtOccupyQuantity);
                activityTitleExtUpdateRequest.setActivityOccupyFee(nowExtOccupyFee);
                log.info("更新活动Ext表对象:"+JSON.toJSONString(activityTitleExtUpdateRequest));
                UpdateActivityTitleExtForVersionResponse extForVersion = activityTitleExtService.updateActivityTitleExtForVersion(activityTitleExtUpdateRequest);
                if (Objects.isNull(extForVersion) || Objects.isNull(extForVersion.getCount()) || extForVersion.getCount() == 0) {
                    log.warn("交货单回补活动失败!更新活动Ext失败!" + JSON.toJSONString(activityTitleExtUpdateRequest));
                    return true;
                }
                log.info("交货单回补活动成功!记录表ID:" + activityUseRecordRelationSDO.getId() + ",原始记录:" + JSON.toJSONString(activityUseRecordRelationSDO));
            }
//            }
        }}
        return true;
    }

    @Override
    @ProcessInvoker(printLog = true)
    public Result<Void> invoiceCreateMessageDeal(InvoiceCreateMessageDealRequest invoiceCreateMessageDealRequest) {
        log.info("invoiceCreateMessageDeal messageJSON:" + invoiceCreateMessageDealRequest.getMessage());

        InvoiceOrderSDO invoiceOrderSDO = JSONObject.parseObject(invoiceCreateMessageDealRequest.getMessage(), InvoiceOrderSDO.class);
        //如果不是销售订单发票，直接返回不处理
//        if (StringUtil.isBlank(invoiceOrderSDO.getSourceOrderId())) {
//            return Result.success(null);
//        }
        List<InvoiceOrderDetailSDO> items = invoiceOrderSDO.getDetailList();
//        Map<String,List<InvoiceOrderDetailSDO>> saleOrderInvoiceDetails = new HashMap<>();

        Map<String,List<InvoiceOrderDetailSDO>> saleOrderInvoiceDetails = items.stream().filter(invoiceOrderDetailSDO -> StringUtils.isNotBlank(invoiceOrderDetailSDO.getSourceOrderId())).collect(Collectors.groupingBy(InvoiceOrderDetailSDO::getSourceOrderId));
        if (MapUtils.isEmpty(saleOrderInvoiceDetails)){
            log.info("invoiceCreateMessageDeal 源单号为空，直接返回成功");
            return Result.success(null);
        }
        Set<String> sourceIds = saleOrderInvoiceDetails.keySet();
        for (String sourceId : sourceIds) {
            OrderPageQueryRequest orderPageQueryRequest = new OrderPageQueryRequest();
            orderPageQueryRequest.setOuterOrderId(sourceId);
            Result<List<OrderPageQueryResponse>> result = orderQueryService.pageQuery(orderPageQueryRequest);
            if (result == null || org.apache.commons.collections4.CollectionUtils.isEmpty(result.getResult())) {
                /*
                 * 通过源单号查询调拨单，若未查到，报错；查到返回success。
                 */
                if (CollectionUtils.isNotEmpty(loadAllocateOrderList(sourceId))) {
                    continue;
                }
                throw new FacadeException("OTS-05-001-10-16-036");
            }
            OrderPageQueryResponse resp = result.getResult().get(0);
            List<InvoiceOrderDetailSDO> invoiceOrderDetailSDOList = saleOrderInvoiceDetails.get(sourceId);
            for (InvoiceOrderDetailSDO invoiceOrderDetailSDO : invoiceOrderDetailSDOList) {
                if (invoiceOrderDetailSDO.getSalesOrderLineId() == null) {
                    log.info("invoiceCreateMessageDeal 发票信息中不包含销售订单号信息 "+ invoiceOrderDetailSDO.getInvoiceOrderId());
                    continue;
                }
                OrderLineLoadListRequest orderLinePageQueryRequest = new OrderLineLoadListRequest();
                orderLinePageQueryRequest.setMainOrderId(resp.getId());
                orderLinePageQueryRequest.setOuterOrderLineId(invoiceOrderDetailSDO.getSalesOrderLineId());
                orderLinePageQueryRequest.setStart(0);
                orderLinePageQueryRequest.setLimit(999);
                Result<List<OrderLine>> orderLineList = orderLineService.loadOrderLineList(orderLinePageQueryRequest);
                if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderLineList.getResult())) {
                    throw new FacadeException("OTS-05-001-10-16-027");
                }
                orderLineList.getResult().stream().forEach(orderLine -> {
                    Map<String, String> orderLineFeatures = JSONObject.parseObject(orderLine.getFeatures(),Map.class);
                    if (MapUtils.isNotEmpty(orderLineFeatures)) {
                        String deliveryDelete = orderLineFeatures.get(SaleOrderConstants.DELIVERY_DELETE);
                        //2022.11.21 交货单删除时会记录交货单号合集  发票更新时如果对应的交货单被删除了, 不更新 发票明细交货单号不为空
//                        if (StringUtils.isNotBlank(deliveryDelete)&&Boolean.TRUE.toString().equalsIgnoreCase(deliveryDelete)){
                        String deliveryOrderId = invoiceOrderDetailSDOList.stream().map(InvoiceOrderDetailSDO::getDeliveryOrderId).findFirst().orElse(null);
                        if (StringUtils.isNotBlank(deliveryDelete)&&StringUtils.isNotBlank(deliveryOrderId) && deliveryDelete.contains(deliveryOrderId)){
                            return;
                        }
                    }
                    Map<String, String> features = new HashMap<>();
                    //发票信息
                    features.put(SaleOrderConstants.INVOICE_ID, invoiceOrderSDO.getInvoiceOrderId());
                    //去前导0赋值发票行号
                    features.put(SaleOrderConstants.INVOICE_NO, String.valueOf(Integer.parseInt(invoiceOrderDetailSDO.getOrderLineId())));
                    features.put(SaleOrderConstants.INVOICE_TYPE, invoiceOrderSDO.getType());
                    features.put(SaleOrderConstants.INVOICE_DATE, DateUtils.toDateStr(invoiceOrderSDO.getSapGenerateTime().getTime(), DateUtils.DATETIME_FORMAT));
                    features.put(SaleOrderConstants.INVOICE_CREATOR, invoiceOrderSDO.getCreator());
                    features.put(SaleOrderConstants.INVOICE_CREATE_TIME, DateUtils.toDateStr(invoiceOrderSDO.getCreateDate().getTime(), DateUtils.DATETIME_FORMAT));
                    features.put(SaleOrderConstants.INVOICE_QTY, String.valueOf(invoiceOrderDetailSDO.getQuantity()));
                    //价格是分，不需要转换，由前端处理展示
//                features.put(SaleOrderConstants.INVOICE_FEE, String.valueOf(invoiceOrderDetailSDO.getSubTotalAmount() / 100));
                    features.put(SaleOrderConstants.INVOICE_PRICE, String.valueOf(invoiceOrderDetailSDO.getPrice()));
                    features.put(SaleOrderConstants.INVOICE_ZK01_FEE, String.valueOf(invoiceOrderDetailSDO.getSubTotalAmount()));

                    Map<String, SubFeaturesRequest> subOrderFeaturesToUpdate = new HashMap<>();
                    SubFeaturesRequest subFeaturesRequest = new SubFeaturesRequest();
                    subFeaturesRequest.setSubOrderFeaturesToUpdate(features);
                    subOrderFeaturesToUpdate.put(String.valueOf(orderLine.getId()), subFeaturesRequest);

                    FeaturesUpdateRequest featuresUpdateRequest = new FeaturesUpdateRequest();
                    featuresUpdateRequest.setMainOrderId(orderLine.getMainOrderId());
                    featuresUpdateRequest.setSubOrderFeaturesToUpdate(subOrderFeaturesToUpdate);
                    orderLineWriteService.updateFeatures(featuresUpdateRequest);
                });
            }
        }


        return Result.success(null);
    }

    @Override
    @ProcessInvoker(printLog = true)
    public Result<Void> consignmentDeleteMessageDeal(ConsignmentDeleteMessageDealRequest consignmentDeleteMessageDealRequest) {
        log.info("consignmentDeleteMessageDeal messageJSON:" + consignmentDeleteMessageDealRequest.getMessage());
        //解析消息
        ConsignmentOrderSDO consignmentOrderSDO = JSONObject.parseObject(consignmentDeleteMessageDealRequest.getMessage(), ConsignmentOrderSDO.class);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            //todo sap需保证 回调在交货单同步之前，否则需一直保留该处理方式
            log.error("交货单删除时，睡眠等待3s，线程异常", e);
        }
        //如果不是销售订单交货单，直接返回不处理
        if (StringUtil.isBlank(consignmentOrderSDO.getOuterSalesOrderId())) {
            return Result.success(null);
        }
        OrderPageQueryRequest orderPageQueryRequest = new OrderPageQueryRequest();
        orderPageQueryRequest.setOuterOrderId(consignmentOrderSDO.getOuterSalesOrderId());
        Result<List<OrderPageQueryResponse>> result = orderQueryService.pageQuery(orderPageQueryRequest);
        log.info("查询销售订单结果：" + JSON.toJSONString(result));
        if (result == null || CollectionUtils.isEmpty(result.getResult())) {
            log.info("交货单删除时，更新销售订单信息，未查询到销售订单，SAP单号：" + consignmentOrderSDO.getOuterSalesOrderId());
            throw new FacadeException("未查询到销售订单");
        }

        OrderPageQueryResponse resp = result.getResult().get(0);
        //是否是换货订单
        boolean isExchangeOrder = isExchangeOrder(resp.getOrderType());

        List<ConsignmentOrderLineSDO> consignmentOrderLineSDOS = consignmentOrderSDO.getConsignmentOrderLineSDOS();
        //是否是换货行的交货单 如果销售单ots行号是偶数 则为换货交货单
        boolean isExchangeLineDeliveryOrder = consignmentOrderLineSDOS.stream().anyMatch(x->StringUtils.isNotBlank(x.getSoLineId()) &&
                Integer.parseInt(x.getSoLineId()) % 2 ==0);
        for (ConsignmentOrderLineSDO consignmentOrderLineSDO : consignmentOrderLineSDOS) {
            if (consignmentOrderSDO.getOuterSalesOrderId() == null || consignmentOrderLineSDO.getOuterSoLineId() == null) {
                return Result.success(null);
            }

            OrderLineLoadListRequest orderLinePageQueryRequest = new OrderLineLoadListRequest();
            orderLinePageQueryRequest.setMainOrderId(resp.getId());
            orderLinePageQueryRequest.setOuterOrderLineId(consignmentOrderLineSDO.getOuterSoLineId());
            orderLinePageQueryRequest.setStart(0);
            orderLinePageQueryRequest.setLimit(999);
            Result<List<OrderLine>> orderLineList = orderLineService.loadOrderLineList(orderLinePageQueryRequest);
            if (CollectionUtils.isEmpty(orderLineList.getResult())) {
                log.info("交货单删除时，更新销售订单信息，未查询到销售订单，SAP单号：" + consignmentOrderSDO.getOuterSalesOrderId());
                throw new FacadeException("未查询到销售订单行");
            }
            OrderLine orderLine = orderLineList.getResult().get(0);
            //换货行标记
            boolean isExchangeLine = EXCHANGE.equals(orderLine.getOrderLineTag());
            //交货单类型  和行明细类型一致  换货交货单 换货行
            boolean isBelong =  Objects.equals(isExchangeLineDeliveryOrder,isExchangeLine);

            //删除交货单信息前判断订单上是否有交货单信息
            Map<String,String> featuresMap = JSONObject.parseObject(orderLine.getFeatures(), Map.class);
            if (StringUtils.isNotBlank(orderLine.getRefuseReasonCode()) && StringUtils.isBlank(featuresMap.get("deliveryOrderId"))) {
                continue;
            }
            //如果是换货订单, 且 交货单类型 和 销售单的行类型不一致时,  例如 换货订单的换货交货单不处理退货的行
            if (isExchangeOrder && !isBelong){
                log.info("consignmentDeleteMessageDeal:isExchangeOrder:{},isExchangeLineDeliveryOrder:{},isExchangeLine:{}",isExchangeOrder,isExchangeLineDeliveryOrder,isExchangeLine);
                continue;
            }
            if (StringUtils.isBlank(featuresMap.get("deliveryOrderId"))) {
                log.info("订单行还未同步交货单号信息，SAP单号：" + consignmentOrderSDO.getOuterSalesOrderId());
                throw new FacadeException("订单行上未查找到对应的交货单信息");
            }

            //交货单信息
            List<String> features = new ArrayList<>();
            features.add(SaleOrderConstants.DELIVERY_ORDER_ID);
            features.add(SaleOrderConstants.DELIVERY_ORDER_LINE_NO);
            features.add(SaleOrderConstants.DELIVERY_ORDER_CREATOR);
            features.add(SaleOrderConstants.DELIVERY_ORDER_CREAT_DATE);
            features.add(SaleOrderConstants.DELIVERY_ORDER_QTY);
            features.add(SaleOrderConstants.DELIVERY_ORDER_POD_STATUS);
            features.add(SaleOrderConstants.DELIVERY_ORDER_POD_QTY);
            features.add(SaleOrderConstants.DELIVERY_ORDER_DATE);
            features.add(SaleOrderConstants.DELIVERY_BASE_QUANTITY);

            //发票信息
            features.add(SaleOrderConstants.INVOICE_ID);
            features.add(SaleOrderConstants.INVOICE_NO);
            features.add(SaleOrderConstants.INVOICE_TYPE);
            features.add(SaleOrderConstants.INVOICE_DATE);
            features.add(SaleOrderConstants.INVOICE_CREATOR);
            features.add(SaleOrderConstants.INVOICE_CREATE_TIME);
            features.add(SaleOrderConstants.INVOICE_QTY);
            features.add(SaleOrderConstants.INVOICE_PRICE);
            features.add(SaleOrderConstants.INVOICE_ZK01_FEE);

            Map<String, SubFeaturesRequest> subOrderFeaturesToDelete = new HashMap<>();
            SubFeaturesRequest subFeaturesRequest = new SubFeaturesRequest();
            subFeaturesRequest.setSubOrderFeaturesToDelete(features);
            //是否是删除交货单，再更新子单features时，打标deliveryDelete=true,便于015接收到发票更新以后，remove掉发票相关的数据
            //2022.11.21 更新 交货单删除后 删除标记值为交货单号集合
            HashMap<String, String> bizFeatures = new HashMap<>();
//            bizFeatures.put(SaleOrderConstants.DELIVERY_DELETE,Boolean.TRUE.toString());
            bizFeatures.put(SaleOrderConstants.DELIVERY_DELETE,consignmentOrderSDO.getOuterDeliveryOrderId());
            subFeaturesRequest.setBizFeatures(bizFeatures);
            subOrderFeaturesToDelete.put(String.valueOf(orderLine.getId()), subFeaturesRequest);


            Map<String, String> mainOrderFeaturesToUpdate = new HashMap<>();
            mainOrderFeaturesToUpdate.put(SaleOrderConstants.DELIVERY_ORDER_ID, "");
            //如果是换货的 这里需要传递下 用于删除换货单号
            if (isExchangeOrder){
                mainOrderFeaturesToUpdate.put(SaleOrderConstants.EXCHANGE_ORDER_DELIVERY_ORDER_ID,consignmentOrderSDO.getOuterDeliveryOrderId());
            }
            mainOrderFeaturesToUpdate.put(SaleOrderConstants.EXT_MESSAGE, "");
            FeaturesUpdateRequest featuresUpdateRequest = new FeaturesUpdateRequest();
            featuresUpdateRequest.setMainOrderId(orderLine.getMainOrderId());
            featuresUpdateRequest.setMainOrderFeaturesToDelete(mainOrderFeaturesToUpdate);
            featuresUpdateRequest.setSubOrderFeaturesToDelete(subOrderFeaturesToDelete);
            orderLineWriteService.updateFeatures(featuresUpdateRequest);

            //交货单删除回补活动
            String frontOrderId = resp.getFrontOrderId();
            if (StringUtils.isNotBlank(frontOrderId)){
                deliveryRollBackActivity(orderLine,consignmentOrderLineSDO,frontOrderId,Boolean.TRUE);
            }

        }
        return Result.success(null);
    }

    //是否是换货订单
    public static boolean isExchangeOrder(String orderType){
        return SaleOrderTag.EXCHANGE_ORDER.getCode().equals(orderType) || SaleOrderTag.EXCHANGE_ORDER.getDesc().equals(orderType);
    }

    /**
     * 根据发票源单号查询调拨单
     * @param sourceId 发票源单号
     * @return 调拨单
     */
    private List<AllocateOrder> loadAllocateOrderList(String sourceId) {
        try {
            AllocateOrderLoadListRequest request = new AllocateOrderLoadListRequest();
            request.setOutAllocateOrderId(sourceId);
            log.info("TradeMessageListenerServiceImpl.loadAllocateOrderList.sourceId:" + sourceId);
            Result<List<AllocateOrder>> result = allocateOrderService.loadAllocateOrderList(request);
            if (Objects.nonNull(result)) {
                return result.getResult();
            }
            return null;
        } catch (Exception e) {
            log.error("TradeMessageListenerServiceImpl.loadAllocateOrderList.error", e);
            return null;
        }
    }

    /**
     * 交货单更新订单交货数量消息处理
     */
    @Override
    @ProcessInvoker(printLog = true)
    public Result<Void> consignmentUpdateOrderDeliveryQtyMessageDeal(ConsignmentUpdateOrderDeliveryQtyMessageDealRequest consignmentUpdateOrderDeliveryQtyMessageDealRequest) {
        //解析消息
        ConsignmentOrderSDO consignmentOrderSDO = JSONObject.parseObject(consignmentUpdateOrderDeliveryQtyMessageDealRequest.getOrderJson(),ConsignmentOrderSDO.class);
        log.info("TradeMessageListenerServiceImpl consignmentUpdateOrderDeliveryQtyMessageDeal consignmentOrderSDO",JSON.toJSONString(consignmentOrderSDO));
        //如果不是销售订单交货单，直接返回不处理
        if (StringUtil.isBlank(consignmentOrderSDO.getOuterSalesOrderId())) {
            return Result.success(null);
        }

        OrderPageQueryRequest orderPageQueryRequest = new OrderPageQueryRequest();
        orderPageQueryRequest.setOuterOrderId(consignmentOrderSDO.getOuterSalesOrderId());
        Result<List<OrderPageQueryResponse>> result = orderQueryService.pageQuery(orderPageQueryRequest);
        log.info("TradeMessageListenerServiceImpl consignmentUpdateOrderDeliveryQtyMessageDeal result={}",JSON.toJSONString(result));
        if (result == null || CollectionUtils.isEmpty(result.getResult())) {
            log.info("consignmentUpdateOrderDeliveryQtyMessageDeal_loadOrder_is_null，SAP单号：" + consignmentOrderSDO.getOuterSalesOrderId());
            throw new FacadeException("OTS-05-001-10-16-036");
        }
        OrderPageQueryResponse resp = result.getResult().get(0);
//        Map<String, OrderLine> groupOrderLineMap = getGroupOrderLine(resp);
        OrderLineLoadListRequest orderLineLoadListRequest = new OrderLineLoadListRequest();
        orderLineLoadListRequest.setMainOrderId(resp.getId());
        orderLineLoadListRequest.setStart(0);
        orderLineLoadListRequest.setLimit(999);
        Result<List<OrderLine>> listResult = orderLineService.loadOrderLineList(orderLineLoadListRequest);

        if (Objects.isNull(listResult) || CollectionUtils.isEmpty(listResult.getResult())) {
            log.info("consignmentUpdateOrderDeliveryQtyMessageDeal_loadOrderLineList_is_null");
            return Result.success(null);
        }

        for (OrderLine orderLine :listResult.getResult()) {
            //2023.6.15 业中需求，更新订单累计交货数量
            updateOrderCumulativeDeliveryQty(orderLine, resp);
        }


        return Result.success(null);
    }

    private void updateOrderCumulativeDeliveryQty(OrderLine orderLine, OrderPageQueryResponse order){
            //根据销售单号查询交货单，计算累计交货数量
            ConsignmentOrderLoadListRequest consignmentOrderLoadListRequest = new ConsignmentOrderLoadListRequest();
            consignmentOrderLoadListRequest.setOuterSalesOrderId(order.getOuterId());
            consignmentOrderLoadListRequest.setStatus(1);
            consignmentOrderLoadListRequest.setLimit(1000);
            Result<List<ConsignmentOrder>> consignmentOrderResult = consignmentOrderService.queryByOutDeliveryOrderIds(consignmentOrderLoadListRequest);
            BigDecimal cumulativeDeliveryQty = new BigDecimal(0);
            if (consignmentOrderResult!=null && CollectionUtils.isNotEmpty(consignmentOrderResult.getResult())){
                //批量查询交货子单
                List<String> consignmentOrderIds = consignmentOrderResult.getResult().stream().map(ConsignmentOrder::getId).map(String::valueOf).collect(Collectors.toList());
                BatchQueryRequest batchQueryRequest = new BatchQueryRequest();
                batchQueryRequest.setConsignmentOrderIds(consignmentOrderIds);//因为consignOrderId索引是字符串 所以换成 String
                batchQueryRequest.setLimit(1000);
                Result<List<ConsignmentOrderLine>> consignmentOrderLineResult = consignmentOrderLineService.batchQuery(batchQueryRequest);
                if (consignmentOrderLineResult!=null && CollectionUtils.isNotEmpty(consignmentOrderLineResult.getResult())){
                    List<ConsignmentOrderLine> consignmentOrderLineList = consignmentOrderLineResult.getResult().stream().filter(it->!Objects.equals(0,it.getStatus())).filter(x-> orderLine.getOuterOrderLineId().equals(x.getOuterSoLineId())).collect(Collectors.toList());
                    log.info("TradeMessageListenerServiceImpl_updateOrderCumulativeDeliveryQty_consignmentOrderLineList_req={},result={}",JSONObject.toJSONString(batchQueryRequest),JSONObject.toJSONString(consignmentOrderLineList));
                    cumulativeDeliveryQty = consignmentOrderLineList.stream()
                            .map(x -> {
                                if (StringUtils.isNotBlank(x.getBasicQuantity())) {
                                    return new BigDecimal(x.getBasicQuantity().trim());
                                }
                                return BigDecimal.ZERO;
                            })
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                }
            }

            //前面更新了销售子单，查一次取最新子单的版本号
            LoadOrderLineRequest loadOrderLineRequest = new LoadOrderLineRequest();
            loadOrderLineRequest.setId(String.valueOf(orderLine.getId()));
            OrderLine loadOrderLine = orderLineService.loadOrderLine(loadOrderLineRequest);
            if(Objects.isNull(loadOrderLine)){
                log.error("TradeMessageListenerServiceImpl_updateOrderCumulativeDeliveryQty_loadOrderLine_is_null");
                return;
            }

            UpdateCumulativeDeliveryQuantityRequest updateRequest = new UpdateCumulativeDeliveryQuantityRequest();
            updateRequest.setOrderLineId(loadOrderLine.getId());
            updateRequest.setSyncVersion(loadOrderLine.getSyncVersion());
            // 库存数量*转换系数=销售数量，保留整数，小数位四舍五入
            String cumulativeDeliveryQuantity = cumulativeDeliveryQty.multiply(new BigDecimal(loadOrderLine.getUnitConvert()))
                    .setScale(0, RoundingMode.HALF_UP)
                    .toString();
            updateRequest.setCumulativeDeliveryQuantity(cumulativeDeliveryQuantity);
            UpdateCumulativeDeliveryQuantityResponse updateOrderLineResponse = orderLineService.updateCumulativeDeliveryQuantity(updateRequest);

            log.info("TradeMessageListenerServiceImpl updateOrderCumulativeDeliveryQty updateRequest={},updateOrderLineResponse={}",JSON.toJSONString(updateRequest),JSON.toJSONString(updateOrderLineResponse));
            if (updateOrderLineResponse.getCount() != 1) {
                log.error("TradeMessageListenerServiceImpl_updateOrderCumulativeDeliveryQty_updateOrderLine_fail,{}",JSON.toJSONString(updateRequest));
                throw new FunctionException("OTS-05-001-10-16-055");
            }
//            if(!groupOrderLineMap.isEmpty()){
//                handleGroupOrderLine(groupOrderLineMap,loadOrderLine);
//            }
    }
    private Map<String, OrderLine> getGroupOrderLine(OrderPageQueryResponse resp){
        Map<String, OrderLine> groupOrderLineMap = new HashMap<>();
        //如果不是F-B-b中的B-b
        if(!(OrderCategoryEnum.STOCK.getCode().equals(resp.getOrderCategoryCode())&& !SalesOrderTypeEnum.GROUP_STD_ORDER.getCode().equals(resp.getOrderType()))){
            return groupOrderLineMap;
        }
        try {
            OrderLineLoadListRequest groupOrderLineLoadListRequest = new OrderLineLoadListRequest();
            groupOrderLineLoadListRequest.setMainOrderBizId(resp.getRelationNo());
            groupOrderLineLoadListRequest.setStart(0);
            groupOrderLineLoadListRequest.setLimit(999);
            Result<List<OrderLine>> groupListResult = orderLineService.loadOrderLineList(groupOrderLineLoadListRequest);
            log.info("consignmentUpdateOrderDeliveryQtyMessageDeal groupListResult ={} groupOrderLineLoadListRequest={}",JSON.toJSONString(groupListResult),JSON.toJSONString(groupOrderLineLoadListRequest));
            if (Objects.nonNull(groupListResult) || CollectionUtils.isNotEmpty(groupListResult.getResult())) {
                groupOrderLineMap = groupListResult.getResult().stream().collect(Collectors.toMap(OrderLine::getSerialNumber, Function.identity(), (s1, s2) -> s1));
            }
        }catch (Exception e){
            log.error("consignmentUpdateOrderDeliveryQtyMessageDeal getGroupOrderLine error",e);
        }
        return groupOrderLineMap;
    }
    private void handleGroupOrderLine(Map<String, OrderLine> groupOrderLineMap, OrderLine loadOrderLine) {
        log.info("TradeMessageListenerServiceImpl handleGroupOrderLine groupOrderLineMap={}",JSON.toJSONString(groupOrderLineMap));
        if(!groupOrderLineMap.containsKey(loadOrderLine.getSerialNumber())){
            return;
        }
        try{
            OrderLine groupOrderLine = groupOrderLineMap.get(loadOrderLine.getSerialNumber());
            UpdateCumulativeDeliveryQuantityRequest updateRequest = new UpdateCumulativeDeliveryQuantityRequest();
            updateRequest.setOrderLineId(groupOrderLine.getId());
            updateRequest.setSyncVersion(groupOrderLine.getSyncVersion());
            updateRequest.setCumulativeDeliveryQuantity(loadOrderLine.getCumulativeDeliveryQuantity());
            UpdateCumulativeDeliveryQuantityResponse updateOrderLineResponse = orderLineService.updateCumulativeDeliveryQuantity(updateRequest);
            log.info("TradeMessageListenerServiceImpl handleGroupOrderLine updateRequest={},updateOrderLineResponse={}",JSON.toJSONString(updateRequest),JSON.toJSONString(updateOrderLineResponse));
        }catch (Exception e){
            log.error("TradeMessageListenerServiceImpl handleGroupOrderLine error",e);
        }
    }

}
